Skip to content

Add supply-chain CI gates and adversarial fuzz evals#311

Merged
TeoSlayer merged 1 commit into
mainfrom
ci/security-hardening-fuzz
Jun 22, 2026
Merged

Add supply-chain CI gates and adversarial fuzz evals#311
TeoSlayer merged 1 commit into
mainfrom
ci/security-hardening-fuzz

Conversation

@TeoSlayer

Copy link
Copy Markdown
Collaborator

Summary

Hardens CI security and adds adversarial/fuzz EVAL coverage for the trust-boundary code paths (keyexchange wire parsing, badge/recovery IPC, badge node binding). Fills the gaps left by the existing CodeQL ("Analyze Go", default query suite) and the gitleaks/detect-private-key pre-commit hook — neither of which protects direct pushes or unhooked clones.

CI: present vs added

Already present (unchanged): CodeQL "Analyze Go" (default suite + one query-filter exclude — NOT security-extended), Architecture gates (lock-graph -race ./pkg/daemon/... + stress harness), CI Go (mac+ubuntu, go vet/build/-short), nightly integration + 7 fuzz suites, cli-reference-check, dependabot (gomod/npm/actions, weekly), pre-commit gitleaks v8.21.2 + detect-private-key/detect-aws/large-files. (No Snyk workflow exists in this repo.)

Added:

New gating check (status-check name) Job Gating?
govulncheck security.yml Yes — known-vuln deps + called stdlib
gitleaks security.yml Yes — secret scan on push + PR
Dependency review dependency-review.yml Yes (PR only) — vuln/license deps
Race detector — all library packages (-short) architecture.yml Yes — broad -race over pkg/cmd/internal
gosec (SARIF, non-gating) security.yml No — SARIF→Security tab (see below)

Also: architecture.yml setup-go pinned to go.mod; go.mod bumped to go 1.25.11.

Scanner findings + resolutions

  • govulncheck: found GO-2026-5037 (crypto/x509) and GO-2026-5039 (net/textproto) — both stdlib, called from telemetry/appstore, fixed in go1.25.11. Resolved by bumping go.mod go 1.25.11 (genuine fix, not an exclusion). Now clean.
  • gosec: 262 pre-existing findings, all by-design for a local CLI (G304/G703 reading user-named files, G204/G702 shelling to git/$EDITOR, G115 port/seq int casts, G404 math/rand jitter, G104 best-effort cleanup). Zero HIGH/MEDIUM in the daemon/library trust boundary once those classes are set aside. Rather than a giant cleanup PR or a dishonest blanket-disable, gosec runs non-gating, SARIF→Security tab — the same model CodeQL already uses. Flip continue-on-error off once triaged.
  • gitleaks: 11 history false positives — placeholder Bearer <token> / "token":"<...>" in web/src/pages/*.astro docs, and a pc2.PeerX25519Key == pc1.PeerX25519Key field comparison in a tunnel test. Resolved with a tight, documented .gitleaks.toml allowlist (extends default ruleset). Full history + working tree now clean.

Adversarial / fuzz EVALs

  • pkg/daemon/keyexchange/zz_fuzz_frame_test.goFuzzHandleAuthFrame / FuzzHandleUnauthFrame: fuzz the PILA/PILK wire parsers. Assert no panic and fail-closed (a random/forged auth frame must never be accepted). ~40–70k execs/s, clean.
  • pkg/daemon/zz_fuzz_badge_ipc_test.goFuzzHandleSubmitBadgePayload, FuzzHandleEnrollRecoveryPayload (drive the real IPC handlers; fail-closed with nil registry conn), FuzzParseBadgeCredentials (badgeverify Parse/ParseEnrollment/ParseRecovery). No panic.
  • cmd/pilotctl/zz_verify_node_binding_test.go — adversarial: a badge bound to NodeID A presented for NodeID B is rejected by VerifyForNode (cross-node replay), and a forged-signature badge for its own node still fails closed (proving binding + crypto are independent gates).
  • The rotate-key/sign race regression TestConcurrentRotateKeyAndSign (pkg/daemon, from Fix data race between key rotation and registry signer #308) is covered by both the existing un-short ./pkg/daemon/... race step and the new broad -race -short step.

Validation (GOWORK=off, go1.25.11)

  • go build ./cmd/daemon ./cmd/pilotctl ✓ · go vet ./... ✓ · gofmt clean ✓
  • go test -race -short -parallel 4 ./pkg/daemon ./pkg/daemon/keyexchange ./cmd/pilotctl
  • All 5 fuzz targets run clean (no crashers); new pilotctl binding tests pass
  • govulncheck clean · gitleaks clean (history + tree) · gosec SARIF generates (262 results, exit 0 under -no-fail)
  • Pre-existing macOS-only sandbox TempDir: permission denied (and the known TestWriteLoopExitsOnWriteDeadline sun_path failure) are environment artifacts, not regressions — Linux CI is the gate.

Do not merge — for review.

Fill the security-CI gaps that CodeQL (default query suite) and the
gitleaks pre-commit hook don't cover, and add adversarial/fuzz EVAL
coverage for the security-critical trust boundaries.

CI:
- security.yml: govulncheck (gating), gitleaks (gating, push+PR), and
  gosec SARIF upload (non-gating, GitHub Security tab) — the pre-commit
  hook can't protect direct pushes or unhooked clones.
- dependency-review.yml: flags vulnerable/disallowed-license deps on PRs.
- architecture.yml: add a broad -race -short job over pkg/cmd/internal
  (-parallel 4) so any library data race fails CI, not just the daemon
  lock graph; pin setup-go to go.mod.
- Bump go.mod to go 1.25.11 to clear GO-2026-5037 / GO-2026-5039 stdlib
  vulns that govulncheck flags as called from telemetry/appstore.
- .gitleaks.toml: documented allowlist for 11 history false positives
  (placeholder bearer tokens in .astro docs, an X25519 field comparison
  in a tunnel test).

Tests:
- keyexchange frame fuzzers (PILA/PILK): no panic, fail-closed (a random
  auth frame must never be accepted).
- badge/recovery IPC payload fuzzers + badgeverify parser fuzzer: no
  panic, fail-closed with no registry connection.
- pilotctl adversarial test: a badge bound to a different NodeID is
  rejected by VerifyForNode, and a forged-signature badge for its own
  node still fails closed.
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@TeoSlayer TeoSlayer merged commit 73d47ef into main Jun 22, 2026
13 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants